/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.logging.appender;

import java.io.File;

import org.zhiqim.kernel.util.DateTimes;

/**
 * 日期滚动文件增加器，根据日期切换日志文件，格式如info.log.2014-02-28,info.log..2014-03-01,...
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class FileDailyAppender extends FileAppender
{
    private final Object lock = new Object();      //文件锁
    private volatile String fileDate;              //文件日志对应的日期
    
    @Override
    public void append(int level, String message, Throwable throwable)
    {
        String curDate = DateTimes.getDateString();
        if (!curDate.equals(fileDate))
            convertWriter(curDate);
        
        print(level, message, throwable);
    }
    
    @Override
    public void setFilePath(String filePath)
    {
        super.setFilePath(filePath);
        convertWriter(DateTimes.getDateString());
    }
    
    /** 变更文件输出器 */
    private void convertWriter(String date)
    {
        synchronized (lock)
        {
            //再次判断，因为同步之前可能并发到达，第一个处理了，后面的无需处理
            if (date.equals(fileDate))
                return;
            
            super.closeWriter();                        //关闭可能的输出器
            super.setFilePathOnly(newFilePath(date));   //设置当前文件路径为加日期的文件路径
            super.createWriter();                       //创建当前输出器
            
            this.removeMaxFile();                       //删除多余的日志文件
            this.fileDate = date;                       //最后设置日期为当前日期
        }
    }
    
    /** 删除多余的日志文件，最多保存fileMaxNum天数 */
    private void removeMaxFile()
    {
        if (fileMaxNum <= 0)
        {//配置为0表示不删除
            return;
        }
        
        //把fileMaxNum之前的文件删除，一般一天一次，也只是删一个文件，除非修改配置文件
        String maxIndexDate = DateTimes.getPreviousDateString(fileMaxNum);
        
        File dir = new File(fileDir);
        for (File file : dir.listFiles())
        {
            if (!file.isFile() || file.getName().length() < 10 || !file.getName().endsWith("." + fileName))
                continue;
            
            String date = file.getName().substring(0, 10);
            if (date.compareTo(maxIndexDate) < 0)
                file.delete();
        }
    }
    
    private String newFilePath(String date)
    {
        return new StringBuilder(fileDir).append("/").append(date).append(".").append(fileName).toString();
    }
}
